/*      */ package com.zimbra.cs.account.accesscontrol;
/*      */ 
/*      */ import com.google.common.collect.ImmutableList;
/*      */ import com.google.common.collect.Multimap;
/*      */ import com.google.common.collect.TreeMultimap;
/*      */ import com.zimbra.common.localconfig.DebugConfig;
/*      */ import com.zimbra.common.localconfig.KnownKey;
/*      */ import com.zimbra.common.localconfig.LC;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.util.CliUtil;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.SetUtil;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.account.AccountServiceException;
/*      */ import com.zimbra.cs.account.AttributeClass;
/*      */ import com.zimbra.cs.account.AttributeManager;
/*      */ import com.zimbra.cs.account.FileGenUtil;
/*      */ import java.io.BufferedWriter;
/*      */ import java.io.File;
/*      */ import java.io.FileWriter;
/*      */ import java.io.IOException;
/*      */ import java.io.PrintStream;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Arrays;
/*      */ import java.util.Collections;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ import java.util.TreeMap;
/*      */ import java.util.TreeSet;
/*      */ import org.apache.commons.cli.CommandLine;
/*      */ import org.apache.commons.cli.CommandLineParser;
/*      */ import org.apache.commons.cli.GnuParser;
/*      */ import org.apache.commons.cli.HelpFormatter;
/*      */ import org.apache.commons.cli.Options;
/*      */ import org.apache.commons.cli.ParseException;
/*      */ import org.dom4j.Document;
/*      */ import org.dom4j.DocumentException;
/*      */ import org.dom4j.DocumentHelper;
/*      */ import org.dom4j.Element;
/*      */ import org.dom4j.io.OutputFormat;
/*      */ import org.dom4j.io.SAXReader;
/*      */ import org.dom4j.io.XMLWriter;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public class RightManager
/*      */ {
/*      */   private static final String E_A = "a";
/*      */   private static final String E_ATTRS = "attrs";
/*      */   private static final String E_DEFAULT = "default";
/*      */   private static final String E_DESC = "desc";
/*      */   private static final String E_HELP = "help";
/*      */   private static final String E_INCLUDE = "include";
/*      */   private static final String E_ITEM = "item";
/*      */   private static final String E_R = "r";
/*      */   private static final String E_RIGHTS = "rights";
/*      */   private static final String E_RIGHT = "right";
/*      */   private static final String E_ROOT = "root";
/*      */   private static final String E_UI = "ui";
/*      */   private static final String A_CACHE = "cache";
/*      */   private static final String A_FALLBACK = "fallback";
/*      */   private static final String A_FILE = "file";
/*      */   private static final String A_GRANT_TARGET_TYPE = "grantTargetType";
/*      */   private static final String A_LIMIT = "l";
/*      */   private static final String A_N = "n";
/*      */   private static final String A_NAME = "name";
/*      */   private static final String A_TARGET_TYPE = "targetType";
/*      */   private static final String A_TYPE = "type";
/*      */   private static final String A_USER_RIGHT = "userRight";
/*      */   private static final String TARGET_TYPE_DELIMITER = ",";
/*      */   private static RightManager mInstance;
/*  100 */   private Map<String, UserRight> sUserRights = new TreeMap();
/*  101 */   private Map<String, AdminRight> sAdminRights = new TreeMap();
/*  102 */   private Map<String, Help> sHelp = new TreeMap();
/*  103 */   private Map<String, UI> sUI = new TreeMap();
/*      */   
/*      */   private static class CoreRightDefFiles {
/*  106 */     private static final HashSet<String> sCoreRightDefFiles = new HashSet();
/*      */     
/*      */     static void init(boolean unittest) {
/*  109 */       sCoreRightDefFiles.add("zimbra-rights.xml");
/*  110 */       sCoreRightDefFiles.add("zimbra-user-rights.xml");
/*      */       
/*  112 */       if ((unittest) || (DebugConfig.running_unittest)) {
/*  113 */         sCoreRightDefFiles.add("rights-unittest.xml");
/*      */       }
/*      */     }
/*      */     
/*      */     static boolean isCoreRightFile(File file) {
/*  118 */       return sCoreRightDefFiles.contains(file.getName());
/*      */     }
/*      */     
/*      */     static String listCoreDefFiles() {
/*  122 */       StringBuilder sb = new StringBuilder();
/*  123 */       boolean first = true;
/*  124 */       for (String file : sCoreRightDefFiles) {
/*  125 */         if (!first) {
/*  126 */           sb.append(", ");
/*      */         } else
/*  128 */           first = false;
/*  129 */         sb.append(file);
/*      */       }
/*  131 */       return sb.toString();
/*      */     }
/*      */   }
/*      */   
/*      */   public static synchronized RightManager getInstance() throws ServiceException {
/*  136 */     return getInstance(false);
/*      */   }
/*      */   
/*      */   public static synchronized RightManager getInstance(boolean unittest) throws ServiceException
/*      */   {
/*  141 */     return getInstance(LC.zimbra_rights_directory.value(), unittest);
/*      */   }
/*      */   
/*      */   private static synchronized RightManager getInstance(String dir, boolean unittest) throws ServiceException
/*      */   {
/*  146 */     if (mInstance != null) {
/*  147 */       return mInstance;
/*      */     }
/*      */     
/*  150 */     mInstance = new RightManager(dir, unittest);
/*      */     try
/*      */     {
/*  153 */       Right.init(mInstance);
/*      */     } catch (ServiceException e) {
/*  155 */       ZimbraLog.acl.error("failed to initialize known right from: " + dir, e);
/*  156 */       throw e;
/*      */     }
/*  158 */     return mInstance;
/*      */   }
/*      */   
/*      */   private RightManager(String dir, boolean unittest) throws ServiceException {
/*  162 */     CoreRightDefFiles.init(unittest);
/*      */     
/*  164 */     File fdir = new File(dir);
/*  165 */     if (!fdir.exists()) {
/*  166 */       throw ServiceException.FAILURE("rights directory does not exists: " + dir, null);
/*      */     }
/*  168 */     if (!fdir.isDirectory()) {
/*  169 */       throw ServiceException.FAILURE("rights directory is not a directory: " + dir, null);
/*      */     }
/*      */     
/*  172 */     ZimbraLog.acl.debug("Loading rights from " + fdir.getAbsolutePath());
/*      */     
/*  174 */     File[] files = fdir.listFiles();
/*  175 */     List<File> yetToProcess = new ArrayList(Arrays.asList(files));
/*  176 */     List<File> processed = new ArrayList();
/*      */     
/*  178 */     while (!yetToProcess.isEmpty()) {
/*  179 */       File file = (File)yetToProcess.get(0);
/*      */       
/*  181 */       if ((!file.getPath().endsWith(".xml")) || (!file.isFile())) {
/*  182 */         ZimbraLog.acl.warn("while loading rights, ignoring none .xml file or sub folder: " + file);
/*  183 */         yetToProcess.remove(file);
/*      */       }
/*      */       else
/*      */       {
/*      */         try {
/*  188 */           boolean done = loadSystemRights(file, processed, files);
/*  189 */           if (done) {
/*  190 */             processed.add(file);
/*  191 */             yetToProcess.remove(file);
/*      */           }
/*      */           else {
/*  194 */             yetToProcess.remove(file);
/*  195 */             yetToProcess.add(file);
/*      */           }
/*      */         } catch (DocumentException de) {
/*  198 */           throw ServiceException.PARSE_ERROR("error loading rights file: " + file, de);
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*  204 */   private boolean getBoolean(String value) throws ServiceException { if ("1".equals(value))
/*  205 */       return true;
/*  206 */     if ("0".equals(value)) {
/*  207 */       return false;
/*      */     }
/*  209 */     throw ServiceException.PARSE_ERROR("invalid value:" + value, null);
/*      */   }
/*      */   
/*      */   private boolean getBooleanAttr(Element elem, String attr) throws ServiceException {
/*  213 */     String value = elem.attributeValue(attr);
/*  214 */     if (value == null)
/*  215 */       throw ServiceException.PARSE_ERROR("missing required attribute: " + attr, null);
/*  216 */     return getBoolean(value);
/*      */   }
/*      */   
/*      */   private boolean getBooleanAttr(Element elem, String attr, boolean defaultValue) throws ServiceException
/*      */   {
/*  221 */     String value = elem.attributeValue(attr);
/*  222 */     if (value == null)
/*  223 */       return defaultValue;
/*  224 */     return getBoolean(value);
/*      */   }
/*      */   
/*      */   private void parseDesc(Element eDesc, Right right) throws ServiceException {
/*  228 */     if (right.getDesc() != null)
/*  229 */       throw ServiceException.PARSE_ERROR("multiple desc", null);
/*  230 */     right.setDesc(eDesc.getText());
/*      */   }
/*      */   
/*      */   private void parseHelp(Element eHelp, Right right) throws ServiceException {
/*  234 */     if (right.getHelp() != null) {
/*  235 */       throw ServiceException.PARSE_ERROR("multiple help", null);
/*      */     }
/*      */     
/*  238 */     String helpName = eHelp.attributeValue("name");
/*  239 */     if (helpName == null) {
/*  240 */       throw ServiceException.PARSE_ERROR("missing help name", null);
/*      */     }
/*      */     
/*  243 */     Help help = (Help)this.sHelp.get(helpName);
/*      */     
/*  245 */     if (help == null) {
/*  246 */       throw ServiceException.PARSE_ERROR("no such help: " + helpName, null);
/*      */     }
/*      */     
/*  249 */     right.setHelp(help);
/*      */   }
/*      */   
/*      */   private void parseUI(Element eUI, Right right) throws ServiceException {
/*  253 */     if (right.getUI() != null) {
/*  254 */       throw ServiceException.PARSE_ERROR("multiple ui for right " + right.getName(), null);
/*      */     }
/*      */     
/*  257 */     String uiName = eUI.attributeValue("name");
/*  258 */     if (uiName == null) {
/*  259 */       throw ServiceException.PARSE_ERROR("missing ui name", null);
/*      */     }
/*      */     
/*  262 */     UI ui = (UI)this.sUI.get(uiName);
/*      */     
/*  264 */     if (ui == null) {
/*  265 */       throw ServiceException.PARSE_ERROR("no such ui: " + uiName, null);
/*      */     }
/*      */     
/*  268 */     right.setUI(ui);
/*      */   }
/*      */   
/*      */   private void parseDefault(Element eDefault, Right right) throws ServiceException {
/*  272 */     String defaultValue = eDefault.getText();
/*  273 */     if ("allow".equalsIgnoreCase(defaultValue)) {
/*  274 */       right.setDefault(Boolean.TRUE);
/*  275 */     } else if ("deny".equalsIgnoreCase(defaultValue)) {
/*  276 */       right.setDefault(Boolean.FALSE);
/*      */     } else
/*  278 */       throw ServiceException.PARSE_ERROR("invalid default value: " + defaultValue, null);
/*      */   }
/*      */   
/*      */   private void parseAttr(Element eAttr, AttrRight right) throws ServiceException {
/*  282 */     String attrName = eAttr.attributeValue("n");
/*  283 */     if (attrName == null) {
/*  284 */       throw ServiceException.PARSE_ERROR("missing attr name", null);
/*      */     }
/*  286 */     right.validateAttr(attrName);
/*  287 */     right.addAttr(attrName);
/*      */   }
/*      */   
/*      */   private void parseAttrs(Element eAttrs, Right right) throws ServiceException {
/*  291 */     if (!(right instanceof AttrRight)) {
/*  292 */       throw ServiceException.PARSE_ERROR("attrs is only allowed for admin getAttrs or setAttrs right", null);
/*      */     }
/*      */     
/*  295 */     AttrRight attrRight = (AttrRight)right;
/*  296 */     for (Iterator elemIter = eAttrs.elementIterator(); elemIter.hasNext();) {
/*  297 */       Element elem = (Element)elemIter.next();
/*  298 */       if (elem.getName().equals("a")) {
/*  299 */         parseAttr(elem, attrRight);
/*      */       } else
/*  301 */         throw ServiceException.PARSE_ERROR("invalid element: " + elem.getName(), null);
/*      */     }
/*      */   }
/*      */   
/*      */   private void parseRight(Element eAttr, ComboRight right) throws ServiceException {
/*  306 */     String rightName = eAttr.attributeValue("n");
/*  307 */     if (rightName == null) {
/*  308 */       throw ServiceException.PARSE_ERROR("missing right name", null);
/*      */     }
/*  310 */     Right r = getRight(rightName);
/*      */     
/*  312 */     if (r.isUserRight()) {
/*  313 */       throw ServiceException.PARSE_ERROR(r.getName() + " is an user right, combo right " + "can only contain admin rights.", null);
/*      */     }
/*      */     
/*  316 */     right.addRight(r);
/*      */   }
/*      */   
/*      */   private void parseRights(Element eAttrs, Right right) throws ServiceException {
/*  320 */     if (!(right instanceof ComboRight)) {
/*  321 */       throw ServiceException.PARSE_ERROR("rights is only allowed for admin combo right", null);
/*      */     }
/*  323 */     ComboRight comboRight = (ComboRight)right;
/*      */     
/*  325 */     for (Iterator elemIter = eAttrs.elementIterator(); elemIter.hasNext();) {
/*  326 */       Element elem = (Element)elemIter.next();
/*  327 */       if (elem.getName().equals("r")) {
/*  328 */         parseRight(elem, comboRight);
/*      */       } else
/*  330 */         throw ServiceException.PARSE_ERROR("invalid element: " + elem.getName(), null);
/*      */     }
/*      */   }
/*      */   
/*      */   private Right parseRight(Element eRight) throws ServiceException {
/*  335 */     String name = eRight.attributeValue("name");
/*      */     
/*      */ 
/*  338 */     if (name.contains(".")) {
/*  339 */       throw ServiceException.PARSE_ERROR("righ name cannot contain dot(.): " + name, null);
/*      */     }
/*  341 */     boolean userRight = getBooleanAttr(eRight, "userRight", false);
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  346 */     Right.RightType rightType = null;
/*  347 */     String targetTypeStr = eRight.attributeValue("targetType", null);
/*      */     Right right;
/*  349 */     if (userRight) { TargetType targetType;
/*      */       TargetType targetType;
/*  351 */       if (targetTypeStr != null) {
/*  352 */         targetType = TargetType.fromCode(targetTypeStr);
/*      */       } else {
/*  354 */         targetType = TargetType.account;
/*      */       }
/*      */       
/*  357 */       Right right = new UserRight(name);
/*  358 */       right.setTargetType(targetType);
/*      */       
/*  360 */       String fallback = eRight.attributeValue("fallback", null);
/*  361 */       if (fallback != null) {
/*  362 */         CheckRightFallback fb = loadFallback(fallback, right);
/*  363 */         right.setFallback(fb);
/*      */       }
/*      */     }
/*      */     else {
/*  367 */       String rt = eRight.attributeValue("type");
/*  368 */       if (rt == null) {
/*  369 */         throw ServiceException.PARSE_ERROR("missing attribute [type]", null);
/*      */       }
/*  371 */       rightType = Right.RightType.fromString(rt);
/*      */       
/*  373 */       right = AdminRight.newAdminSystemRight(name, rightType);
/*  374 */       if (targetTypeStr != null) {
/*  375 */         String[] taregtTypes = targetTypeStr.split(",");
/*  376 */         for (String tt : taregtTypes) {
/*  377 */           TargetType targetType = TargetType.fromCode(tt);
/*  378 */           right.setTargetType(targetType);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*  383 */     String grantTargetTypeStr = eRight.attributeValue("grantTargetType", null);
/*  384 */     if (grantTargetTypeStr != null) {
/*  385 */       TargetType grantTargetType = TargetType.fromCode(grantTargetTypeStr);
/*  386 */       right.setGrantTargetType(grantTargetType);
/*      */     }
/*      */     
/*  389 */     boolean cache = getBooleanAttr(eRight, "cache", false);
/*  390 */     if (cache) {
/*  391 */       right.setCacheable();
/*      */     }
/*      */     
/*  394 */     for (Iterator elemIter = eRight.elementIterator(); elemIter.hasNext();) {
/*  395 */       Element elem = (Element)elemIter.next();
/*  396 */       if (elem.getName().equals("desc")) {
/*  397 */         parseDesc(elem, right);
/*  398 */       } else if (elem.getName().equals("help")) {
/*  399 */         parseHelp(elem, right);
/*  400 */       } else if (elem.getName().equals("ui")) {
/*  401 */         parseUI(elem, right);
/*  402 */       } else if (elem.getName().equals("default")) {
/*  403 */         parseDefault(elem, right);
/*  404 */       } else if (elem.getName().equals("attrs")) {
/*  405 */         parseAttrs(elem, right);
/*  406 */       } else if (elem.getName().equals("rights")) {
/*  407 */         parseRights(elem, right);
/*      */       } else {
/*  409 */         throw ServiceException.PARSE_ERROR("invalid element: " + elem.getName(), null);
/*      */       }
/*      */     }
/*      */     
/*      */ 
/*  414 */     right.completeRight();
/*      */     
/*  416 */     return right;
/*      */   }
/*      */   
/*      */   private static CheckRightFallback loadFallback(String clazz, Right right) {
/*  420 */     CheckRightFallback cb = null;
/*  421 */     if (clazz == null)
/*  422 */       return null;
/*  423 */     if (clazz.indexOf('.') == -1)
/*  424 */       clazz = "com.zimbra.cs.account.accesscontrol.fallback." + clazz;
/*      */     try {
/*  426 */       cb = (CheckRightFallback)Class.forName(clazz).newInstance();
/*  427 */       if (cb != null)
/*  428 */         cb.setRight(right);
/*      */     } catch (Exception e) {
/*  430 */       ZimbraLog.acl.warn("loadFallback " + clazz + " for right " + right.getName() + " caught exception", e);
/*      */     }
/*  432 */     return cb;
/*      */   }
/*      */   
/*      */   private boolean loadSystemRights(File file, List<File> processedFiles, File[] allFiles) throws DocumentException, ServiceException
/*      */   {
/*  437 */     SAXReader reader = new SAXReader();
/*  438 */     Document doc = reader.read(file);
/*  439 */     Element root = doc.getRootElement();
/*  440 */     if (!root.getName().equals("rights")) {
/*  441 */       throw ServiceException.PARSE_ERROR("root tag is not rights", null);
/*      */     }
/*      */     
/*      */ 
/*  445 */     boolean allowPresetRight = CoreRightDefFiles.isCoreRightFile(file);
/*      */     
/*  447 */     boolean seenRight = false;
/*  448 */     for (Iterator iter = root.elementIterator(); iter.hasNext();) {
/*  449 */       Element elem = (Element)iter.next();
/*      */       
/*      */ 
/*  452 */       if (elem.getName().equals("include"))
/*      */       {
/*  454 */         if (seenRight) {
/*  455 */           throw ServiceException.PARSE_ERROR("include cannot appear after any right definition: " + elem.getName(), null);
/*      */         }
/*      */         
/*      */ 
/*      */ 
/*  460 */         String includeFile = elem.attributeValue("file");
/*      */         
/*      */ 
/*  463 */         boolean foundFile = false;
/*  464 */         for (File f : allFiles) {
/*  465 */           if (f.getName().equals(includeFile)) {
/*  466 */             foundFile = true;
/*  467 */             break;
/*      */           }
/*      */         }
/*  470 */         if (!foundFile) {
/*  471 */           throw ServiceException.PARSE_ERROR("cannot find include file " + includeFile, null);
/*      */         }
/*      */         
/*  474 */         boolean processed = false;
/*  475 */         for (File f : processedFiles) {
/*  476 */           if (f.getName().equals(includeFile)) {
/*  477 */             processed = true;
/*  478 */             break;
/*      */           }
/*      */         }
/*  481 */         if (!processed) {
/*  482 */           return false;
/*      */         }
/*      */         
/*      */       }
/*  486 */       else if (elem.getName().equals("right")) {
/*  487 */         if (!seenRight) {
/*  488 */           seenRight = true;
/*  489 */           ZimbraLog.acl.debug("Loading " + file.getAbsolutePath());
/*      */         }
/*  491 */         loadRight(elem, file, allowPresetRight);
/*  492 */       } else if (elem.getName().equals("help")) {
/*  493 */         loadHelp(elem, file);
/*  494 */       } else if (elem.getName().equals("ui")) {
/*  495 */         loadUI(elem, file);
/*      */       } else {
/*  497 */         throw ServiceException.PARSE_ERROR("unknown element: " + elem.getName(), null);
/*      */       }
/*      */     }
/*      */     
/*  501 */     return true;
/*      */   }
/*      */   
/*      */   private void loadRight(Element eRight, File file, boolean allowPresetRight) throws ServiceException
/*      */   {
/*  506 */     String name = eRight.attributeValue("name");
/*  507 */     if (name == null) {
/*  508 */       throw ServiceException.PARSE_ERROR("no name specified", null);
/*      */     }
/*      */     
/*  511 */     checkName(name);
/*      */     try
/*      */     {
/*  514 */       Right right = parseRight(eRight);
/*  515 */       if ((!allowPresetRight) && (Right.RightType.preset == right.getRightType())) {
/*  516 */         throw ServiceException.PARSE_ERROR("Encountered preset right " + name + " in " + file.getName() + ", preset right can only be defined in one of the core right definition files: " + CoreRightDefFiles.listCoreDefFiles(), null);
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  523 */       if ((right instanceof UserRight)) {
/*  524 */         this.sUserRights.put(name, (UserRight)right);
/*      */       } else {
/*  526 */         this.sAdminRights.put(name, (AdminRight)right);
/*      */       }
/*      */     } catch (ServiceException e) {
/*  529 */       throw ServiceException.PARSE_ERROR("unable to parse right: [" + name + "]", e);
/*      */     }
/*      */   }
/*      */   
/*      */   private void loadHelp(Element eHelp, File file) throws ServiceException {
/*  534 */     String name = eHelp.attributeValue("name");
/*  535 */     if (name == null) {
/*  536 */       throw ServiceException.PARSE_ERROR("no name specified", null);
/*      */     }
/*      */     
/*  539 */     checkName(name);
/*      */     
/*  541 */     Help help = new Help(name);
/*      */     
/*  543 */     for (Iterator elemIter = eHelp.elementIterator(); elemIter.hasNext();) {
/*  544 */       Element elem = (Element)elemIter.next();
/*  545 */       if (elem.getName().equals("desc")) {
/*  546 */         if (help.getDesc() != null) {
/*  547 */           throw ServiceException.PARSE_ERROR("desc for help " + name + " already set", null);
/*      */         }
/*  549 */         help.setDesc(elem.getText());
/*  550 */       } else if (elem.getName().equals("item")) {
/*  551 */         help.addItem(elem.getText());
/*      */       } else {
/*  553 */         throw ServiceException.PARSE_ERROR("invalid element: " + elem.getName(), null);
/*      */       }
/*      */     }
/*      */     
/*      */ 
/*  558 */     help.validate();
/*      */     
/*  560 */     this.sHelp.put(name, help);
/*      */   }
/*      */   
/*      */   private void loadUI(Element eUI, File file) throws ServiceException {
/*  564 */     String name = eUI.attributeValue("name");
/*  565 */     if (name == null) {
/*  566 */       throw ServiceException.PARSE_ERROR("no name specified", null);
/*      */     }
/*      */     
/*  569 */     checkName(name);
/*      */     
/*  571 */     UI ui = new UI(name);
/*      */     
/*  573 */     String desc = eUI.getText();
/*  574 */     ui.setDesc(desc);
/*      */     
/*      */ 
/*  577 */     ui.validate();
/*      */     
/*  579 */     this.sUI.put(name, ui);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private void checkName(String name)
/*      */     throws ServiceException
/*      */   {
/*  591 */     if ((this.sUserRights.containsKey(name)) || (this.sAdminRights.containsKey(name)) || (this.sHelp.containsKey(name)) || (this.sUI.containsKey(name)))
/*      */     {
/*  593 */       throw ServiceException.PARSE_ERROR("right or help or ui " + name + " is already defined", null);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public UserRight getUserRight(String right)
/*      */     throws ServiceException
/*      */   {
/*  602 */     UserRight r = (UserRight)this.sUserRights.get(right);
/*  603 */     if (r == null) {
/*  604 */       throw ServiceException.FAILURE("invalid right " + right, null);
/*      */     }
/*  606 */     return r;
/*      */   }
/*      */   
/*      */   public AdminRight getAdminRight(String right) throws ServiceException {
/*  610 */     AdminRight r = (AdminRight)this.sAdminRights.get(right);
/*  611 */     if (r == null) {
/*  612 */       throw ServiceException.FAILURE("invalid right " + right, null);
/*      */     }
/*  614 */     return r;
/*      */   }
/*      */   
/*      */   public Right getRight(String right) throws ServiceException {
/*  618 */     if (InlineAttrRight.looksLikeOne(right)) {
/*  619 */       return InlineAttrRight.newInlineAttrRight(right);
/*      */     }
/*  621 */     return getRightInternal(right, true);
/*      */   }
/*      */   
/*      */   private Right getRightInternal(String right, boolean mustFind) throws ServiceException
/*      */   {
/*  626 */     Right r = (Right)this.sUserRights.get(right);
/*  627 */     if (r == null) {
/*  628 */       r = (Right)this.sAdminRights.get(right);
/*      */     }
/*      */     
/*  631 */     if ((mustFind) && (r == null)) {
/*  632 */       throw AccountServiceException.NO_SUCH_RIGHT("invalid right " + right);
/*      */     }
/*      */     
/*  635 */     return r;
/*      */   }
/*      */   
/*      */   public Map<String, UserRight> getAllUserRights() {
/*  639 */     return this.sUserRights;
/*      */   }
/*      */   
/*      */   public Map<String, AdminRight> getAllAdminRights() {
/*  643 */     return this.sAdminRights;
/*      */   }
/*      */   
/*      */   private String dump(StringBuilder sb) {
/*  647 */     if (sb == null) {
/*  648 */       sb = new StringBuilder();
/*      */     }
/*      */     
/*  651 */     sb.append("============\n");
/*  652 */     sb.append("user rights:\n");
/*  653 */     sb.append("============\n");
/*  654 */     for (Map.Entry<String, UserRight> ur : getAllUserRights().entrySet()) {
/*  655 */       sb.append("\n------------------------------\n");
/*  656 */       ((UserRight)ur.getValue()).dump(sb);
/*      */     }
/*      */     
/*  659 */     sb.append("\n");
/*  660 */     sb.append("\n");
/*  661 */     sb.append("=============\n");
/*  662 */     sb.append("admin rights:\n");
/*  663 */     sb.append("=============\n");
/*  664 */     for (Map.Entry<String, AdminRight> ar : getAllAdminRights().entrySet()) {
/*  665 */       sb.append("\n------------------------------\n");
/*  666 */       ((AdminRight)ar.getValue()).dump(sb);
/*      */     }
/*      */     
/*  669 */     return sb.toString();
/*      */   }
/*      */   
/*      */   void genRightConst(Right r, StringBuilder sb) {
/*  673 */     sb.append("\n    /**\n");
/*  674 */     if (r.getDesc() != null) {
/*  675 */       sb.append(FileGenUtil.wrapComments(StringUtil.escapeHtml(r.getDesc()), 70, "     * "));
/*  676 */       sb.append("\n");
/*      */     }
/*  678 */     sb.append("     */\n");
/*  679 */     sb.append("    public static final String RT_" + r.getName() + " = \"" + r.getName() + "\";" + "\n");
/*      */   }
/*      */   
/*      */   private String genRightConsts() {
/*  683 */     StringBuilder sb = new StringBuilder();
/*      */     
/*  685 */     sb.append("\n\n");
/*  686 */     sb.append("    /*\n");
/*  687 */     sb.append("    ============\n");
/*  688 */     sb.append("    user rights:\n");
/*  689 */     sb.append("    ============\n");
/*  690 */     sb.append("    */\n\n");
/*  691 */     for (Map.Entry<String, UserRight> ur : getAllUserRights().entrySet()) {
/*  692 */       genRightConst((Right)ur.getValue(), sb);
/*      */     }
/*      */     
/*  695 */     sb.append("\n\n");
/*  696 */     sb.append("    /*\n");
/*  697 */     sb.append("    =============\n");
/*  698 */     sb.append("    admin rights:\n");
/*  699 */     sb.append("    =============\n");
/*  700 */     sb.append("    */\n\n");
/*  701 */     for (Map.Entry<String, AdminRight> ar : getAllAdminRights().entrySet()) {
/*  702 */       genRightConst((Right)ar.getValue(), sb);
/*      */     }
/*      */     
/*  705 */     return sb.toString();
/*      */   }
/*      */   
/*      */   private String genAdminRights() {
/*  709 */     StringBuilder sb = new StringBuilder();
/*      */     
/*  711 */     sb.append("\n\n");
/*  712 */     for (AdminRight r : getAllAdminRights().values()) {
/*  713 */       sb.append("    public static AdminRight R_" + r.getName() + ";" + "\n");
/*      */     }
/*      */     
/*  716 */     sb.append("\n\n");
/*  717 */     sb.append("    public static void init(RightManager rm) throws ServiceException {\n");
/*  718 */     for (AdminRight r : getAllAdminRights().values()) {
/*  719 */       String s = String.format("        R_%-36s = rm.getAdminRight(Right.RT_%s);\n", new Object[] { r.getName(), r.getName() });
/*      */       
/*  721 */       sb.append(s);
/*      */     }
/*  723 */     sb.append("    }\n");
/*  724 */     return sb.toString();
/*      */   }
/*      */   
/*      */   private String genUserRights() {
/*  728 */     StringBuilder sb = new StringBuilder();
/*      */     
/*  730 */     sb.append("\n\n");
/*  731 */     for (UserRight r : getAllUserRights().values()) {
/*  732 */       sb.append("    public static UserRight R_" + r.getName() + ";" + "\n");
/*      */     }
/*      */     
/*  735 */     sb.append("\n\n");
/*  736 */     sb.append("    public static void init(RightManager rm) throws ServiceException {\n");
/*  737 */     for (UserRight r : getAllUserRights().values()) {
/*  738 */       String s = String.format("        R_%-36s = rm.getUserRight(Right.RT_%s);\n", new Object[] { r.getName(), r.getName() });
/*      */       
/*  740 */       sb.append(s);
/*      */     }
/*  742 */     sb.append("    }\n");
/*  743 */     return sb.toString();
/*      */   }
/*      */   
/*      */   private String genMessageProperties() throws ServiceException {
/*  747 */     StringBuilder result = new StringBuilder();
/*      */     
/*  749 */     result.append(FileGenUtil.genDoNotModifyDisclaimer("#", RightManager.class.getSimpleName()));
/*  750 */     result.append("# Zimbra rights");
/*  751 */     result.append("\n\n");
/*      */     
/*  753 */     genMessageProperties(result, getAllUserRights());
/*  754 */     result.append("\n\n");
/*  755 */     genMessageProperties(result, getAllAdminRights());
/*      */     
/*  757 */     return result.toString();
/*      */   }
/*      */   
/*      */   private void genMessageProperties(StringBuilder result, Map<String, ? extends Right> rights) throws ServiceException
/*      */   {
/*  762 */     List<String> sortedRights = new ArrayList(rights.keySet());
/*  763 */     Collections.sort(sortedRights);
/*      */     
/*  765 */     for (String right : sortedRights) {
/*  766 */       Right r = getRight(right);
/*      */       
/*  768 */       String text = FileGenUtil.wrapComments(r.getDesc(), 80, "  ", " \\").substring(2);
/*  769 */       result.append(r.getName() + " = " + text + "\n");
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private void genAdminDocs(String outputDir)
/*      */     throws ServiceException, IOException
/*      */   {
/*  784 */     if (!outputDir.endsWith("/")) {
/*  785 */       outputDir = outputDir + "/";
/*      */     }
/*      */     
/*  788 */     List<AdminRight> rootRights = ImmutableList.of(Rights.Admin.R_adminConsoleRights);
/*      */     
/*      */ 
/*  791 */     for (AdminRight right : rootRights) {
/*  792 */       Multimap<UI, Right> uiMap = TreeMultimap.create();
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  798 */       Document document = DocumentHelper.createDocument();
/*      */       
/*  800 */       Element rightsRoot = document.addElement("root");
/*  801 */       genAdminDocByRight(rightsRoot, right, uiMap);
/*  802 */       writeXML(outputDir + right.getName() + "-expanded.xml", document);
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  808 */       document = DocumentHelper.createDocument();
/*  809 */       Element uiRoot = document.addElement("root");
/*  810 */       genAdminDocByUI(uiRoot, uiMap);
/*  811 */       writeXML(outputDir + right.getName() + "-ui.xml", document);
/*      */     }
/*      */   }
/*      */   
/*      */   private void writeXML(String fileName, Document document)
/*      */     throws IOException
/*      */   {
/*  818 */     OutputFormat format = OutputFormat.createPrettyPrint();
/*      */     
/*  820 */     BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
/*  821 */     XMLWriter xmlWriter = new XMLWriter(writer, format);
/*  822 */     xmlWriter.write(document);
/*  823 */     writer.close();
/*      */   }
/*      */   
/*      */   private void genAdminDocByRight(Element parent, Right right, Multimap<UI, Right> uiMap) throws ServiceException
/*      */   {
/*  828 */     Element eRight = parent.addElement("right").addAttribute("name", right.getName()).addAttribute("type", right.getRightType().name());
/*      */     
/*      */ 
/*  831 */     eRight.addElement("desc").setText(right.getDesc());
/*      */     
/*  833 */     UI ui = right.getUI();
/*  834 */     if (ui != null) {
/*  835 */       eRight.addElement("ui").setText(ui.getDesc());
/*  836 */       uiMap.put(ui, right);
/*      */     }
/*      */     Element eAttrs;
/*  839 */     if (right.isComboRight()) {
/*  840 */       ComboRight comboRight = (ComboRight)right;
/*  841 */       for (Right childRight : comboRight.getRights()) {
/*  842 */         genAdminDocByRight(eRight, childRight, uiMap);
/*      */       }
/*  844 */     } else if (right.isPresetRight()) {
/*  845 */       eRight.addAttribute("targetType", right.getTargetTypeStr());
/*  846 */     } else if (right.isAttrRight()) {
/*  847 */       eRight.addAttribute("targetType", right.getTargetTypeStr());
/*      */       
/*  849 */       AttrRight attrRight = (AttrRight)right;
/*  850 */       if (!attrRight.allAttrs()) {
/*  851 */         eAttrs = eRight.addElement("attrs");
/*  852 */         for (String attr : attrRight.getAttrs()) {
/*  853 */           eAttrs.addElement("a").addAttribute("n", attr);
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   private void genAdminDocByUI(Element parent, Multimap<UI, Right> uiMap) {
/*  860 */     for (Map.Entry<UI, Right> entry : uiMap.entries()) {
/*  861 */       UI ui = (UI)entry.getKey();
/*  862 */       Right right = (Right)entry.getValue();
/*      */       
/*  864 */       Element eUI = parent.addElement("ui");
/*  865 */       eUI.addAttribute("desc", ui.getDesc());
/*  866 */       eUI.addAttribute("right", right.getName());
/*      */     }
/*      */   }
/*      */   
/*      */   private static class CL {
/*  871 */     private static Options sOptions = new Options();
/*      */     
/*      */     static {
/*  874 */       sOptions.addOption("h", "help", false, "display this usage info");
/*      */       
/*  876 */       sOptions.addOption("a", "action", true, "action, one of genRightConsts, genAdminRights, genUserRights, genMessagePrperties");
/*      */       
/*  878 */       sOptions.addOption("i", "input", true, "rights definition xml input directory");
/*      */       
/*  880 */       sOptions.addOption("o", "output", true, "output directory");
/*      */       
/*  882 */       sOptions.addOption("r", "regenerateFile", true, "file to regenerate");
/*      */       
/*  884 */       sOptions.addOption("t", "templateFile", true, "template file");
/*      */     }
/*      */     
/*      */     private static enum Action
/*      */     {
/*  889 */       genRightConsts(true, true, false), 
/*  890 */       genAdminRights(true, true, false), 
/*  891 */       genUserRights(true, true, false), 
/*  892 */       genDomainAdminSetAttrsRights(true, false, false), 
/*  893 */       genMessageProperties(true, true, false), 
/*  894 */       genAdminDocs(false, true, true), 
/*  895 */       validate(false, true, false);
/*      */       
/*      */       boolean regenFileRequred;
/*      */       boolean inputDirRequired;
/*      */       boolean outputDirRequired;
/*      */       
/*      */       private Action(boolean regenFileRequred, boolean inputDirRequired, boolean outputDirRequired) {
/*  902 */         this.regenFileRequred = regenFileRequred;
/*  903 */         this.inputDirRequired = inputDirRequired;
/*  904 */         this.outputDirRequired = outputDirRequired;
/*      */       }
/*      */       
/*      */       private boolean regenFileRequred() {
/*  908 */         return this.regenFileRequred;
/*      */       }
/*      */       
/*      */       private boolean inputDirRequired() {
/*  912 */         return this.inputDirRequired;
/*      */       }
/*      */       
/*      */       private boolean outputDirRequired() {
/*  916 */         return this.outputDirRequired;
/*      */       }
/*      */       
/*      */       private static Action fromString(String str) throws ServiceException {
/*      */         try {
/*  921 */           return valueOf(str);
/*      */         } catch (IllegalArgumentException e) {
/*  923 */           throw ServiceException.INVALID_REQUEST("unknown RightManager CLI action: " + str, e);
/*      */         }
/*      */       }
/*      */     }
/*      */     
/*      */     private static void check() throws ServiceException {
/*  929 */       ZimbraLog.toolSetupLog4j("DEBUG", "/Users/pshao/sandbox/conf/log4j.properties.phoebe");
/*      */       
/*  931 */       RightManager rm = new RightManager("/Users/pshao/p4/main/ZimbraServer/conf/rights", false, null);
/*  932 */       System.out.println(rm.dump(null));
/*      */     }
/*      */     
/*      */     private static void genDomainAdminSetAttrsRights(String outFile, String templateFile) throws Exception
/*      */     {
/*  937 */       Set<String> acctAttrs = getDomainAdminModifiableAttrs(AttributeClass.account);
/*  938 */       Set<String> crAttrs = getDomainAdminModifiableAttrs(AttributeClass.calendarResource);
/*  939 */       Set<String> dlAttrs = getDomainAdminModifiableAttrs(AttributeClass.distributionList);
/*  940 */       Set<String> domainAttrs = getDomainAdminModifiableAttrs(AttributeClass.domain);
/*      */       
/*  942 */       Set<String> acctAndCrAttrs = SetUtil.intersect(acctAttrs, crAttrs);
/*  943 */       Set<String> acctOnlyAttrs = SetUtil.subtract(acctAttrs, crAttrs);
/*  944 */       Set<String> crOnlyAttrs = SetUtil.subtract(crAttrs, acctAttrs);
/*      */       
/*      */ 
/*  947 */       if (acctOnlyAttrs.size() != 0) {
/*  948 */         throw ServiceException.FAILURE("account only attrs is not empty???", null);
/*      */       }
/*  950 */       String acctAndCrAttrsFiller = genAttrs(acctAndCrAttrs);
/*  951 */       String crOnlyAttrsFiller = genAttrs(crOnlyAttrs);
/*  952 */       String dlAttrsFiller = genAttrs(dlAttrs);
/*  953 */       String domainAttrsFiller = genAttrs(domainAttrs);
/*      */       
/*  955 */       Map<String, String> templateFillers = new HashMap();
/*  956 */       templateFillers.put("ACCOUNT_AND_CALENDAR_RESOURCE_ATTRS", acctAndCrAttrsFiller);
/*  957 */       templateFillers.put("CALENDAR_RESOURCE_ATTRS", crOnlyAttrsFiller);
/*  958 */       templateFillers.put("DISTRIBUTION_LIST_ATTRS", dlAttrsFiller);
/*  959 */       templateFillers.put("DOMAIN_ATTRS", domainAttrsFiller);
/*      */       
/*  961 */       FileGenUtil.replaceFile(outFile, templateFile, templateFillers);
/*      */     }
/*      */     
/*      */     private static Set<String> getDomainAdminModifiableAttrs(AttributeClass klass) throws ServiceException
/*      */     {
/*  966 */       AttributeManager am = AttributeManager.getInstance();
/*  967 */       Set<String> allAttrs = am.getAllAttrsInClass(klass);
/*      */       
/*  969 */       Set<String> domainAdminModifiableAttrs = new HashSet();
/*  970 */       for (String attr : allAttrs) {
/*  971 */         if (am.isDomainAdminModifiable(attr, klass)) {
/*  972 */           domainAdminModifiableAttrs.add(attr);
/*      */         }
/*      */       }
/*  975 */       return domainAdminModifiableAttrs;
/*      */     }
/*      */     
/*      */     private static String genAttrs(Set<String> attrs)
/*      */     {
/*  980 */       Set<String> sortedAttrs = new TreeSet(attrs);
/*      */       
/*  982 */       StringBuilder sb = new StringBuilder();
/*  983 */       for (String attr : sortedAttrs) {
/*  984 */         sb.append("    <a n=\"" + attr + "\"/>\n");
/*      */       }
/*  986 */       return sb.toString();
/*      */     }
/*      */     
/*      */     private static void usage(String errmsg) {
/*  990 */       if (errmsg != null) {
/*  991 */         System.out.println(errmsg);
/*      */       }
/*  993 */       HelpFormatter formatter = new HelpFormatter();
/*  994 */       formatter.printHelp("AttributeManager [options] where [options] are one of:", sOptions);
/*  995 */       System.exit(errmsg == null ? 0 : 1);
/*      */     }
/*      */     
/*      */     private static CommandLine parseArgs(String[] args) {
/*  999 */       StringBuffer gotCL = new StringBuffer("cmdline: ");
/* 1000 */       for (int i = 0; i < args.length; i++) {
/* 1001 */         gotCL.append("'").append(args[i]).append("' ");
/*      */       }
/* 1003 */       System.out.println(gotCL);
/*      */       
/* 1005 */       CommandLineParser parser = new GnuParser();
/* 1006 */       CommandLine cl = null;
/*      */       try {
/* 1008 */         cl = parser.parse(sOptions, args);
/*      */       } catch (ParseException pe) {
/* 1010 */         usage(pe.getMessage());
/*      */       }
/* 1012 */       if (cl.hasOption('h')) {
/* 1013 */         usage(null);
/*      */       }
/* 1015 */       return cl;
/*      */     }
/*      */     
/*      */     private static void main(String[] args) throws Exception {
/* 1019 */       CliUtil.toolSetup();
/* 1020 */       CommandLine cl = parseArgs(args);
/*      */       
/* 1022 */       if (!cl.hasOption('a')) {
/* 1023 */         usage("no action specified");
/*      */       }
/* 1025 */       Action action = Action.fromString(cl.getOptionValue('a'));
/*      */       
/* 1027 */       if ((action.regenFileRequred()) && 
/* 1028 */         (!cl.hasOption('r'))) {
/* 1029 */         usage("no regenerate file specified");
/*      */       }
/*      */       
/*      */ 
/* 1033 */       String regenFile = cl.getOptionValue('r');
/*      */       
/* 1035 */       String inputDir = null;
/* 1036 */       RightManager rm = null;
/* 1037 */       if (action.inputDirRequired()) {
/* 1038 */         if (!cl.hasOption('i')) {
/* 1039 */           usage("no input dir specified");
/*      */         }
/* 1041 */         inputDir = cl.getOptionValue('i');
/* 1042 */         rm = RightManager.getInstance(inputDir, false);
/*      */       }
/*      */       
/* 1045 */       String outputDir = null;
/* 1046 */       if (action.outputDirRequired()) {
/* 1047 */         if (!cl.hasOption('o')) {
/* 1048 */           usage("no output dir specified");
/*      */         }
/* 1050 */         outputDir = cl.getOptionValue('o');
/*      */       }
/*      */       
/* 1053 */       switch (RightManager.1.$SwitchMap$com$zimbra$cs$account$accesscontrol$RightManager$CL$Action[action.ordinal()]) {
/*      */       case 1: 
/* 1055 */         FileGenUtil.replaceJavaFile(regenFile, rm.genRightConsts());
/* 1056 */         break;
/*      */       case 2: 
/* 1058 */         FileGenUtil.replaceJavaFile(regenFile, rm.genAdminRights());
/* 1059 */         break;
/*      */       case 3: 
/* 1061 */         FileGenUtil.replaceJavaFile(regenFile, rm.genUserRights());
/* 1062 */         break;
/*      */       case 4: 
/* 1064 */         String templateFile = cl.getOptionValue('t');
/* 1065 */         genDomainAdminSetAttrsRights(regenFile, templateFile);
/* 1066 */         break;
/*      */       case 5: 
/* 1068 */         FileGenUtil.replaceFile(regenFile, rm.genMessageProperties());
/* 1069 */         break;
/*      */       
/*      */       case 6: 
/* 1072 */         rm.genAdminDocs(outputDir);
/* 1073 */         break;
/*      */       
/*      */       case 7: 
/*      */         break;
/*      */       
/*      */       default: 
/* 1079 */         usage("invalid action");
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */   public static void main(String[] args)
/*      */     throws Exception
/*      */   {
/* 1087 */     CL.main(args);
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/accesscontrol/RightManager.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */